package com.ubi.core.framework.request.model;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.ServletRequestDataBinder;

import javax.servlet.ServletRequest;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;

public class RequestModelDataBinder extends ServletRequestDataBinder {

    private final Map<String, String> paramFieldMapping;

    public RequestModelDataBinder(Object target, String objectName, Map<String, String> paramFieldMapping) {
        super(target, objectName);
        this.paramFieldMapping = paramFieldMapping;
    }

    @Override
    protected void addBindValues(MutablePropertyValues mutablePropertyValues, ServletRequest request) {
        this.getTarget();
        for (Map.Entry<String, String> entry : paramFieldMapping.entrySet()) {
            String from = entry.getKey();
            String to = entry.getValue();
            if (mutablePropertyValues.contains(from)) {
                Object value = handleDateValueIfNecessary(mutablePropertyValues.getPropertyValue(from), to);
                mutablePropertyValues.add(to, value);
            }
        }
    }

    private Object handleDateValueIfNecessary(PropertyValue property, String filedName) {
        try {
            Field field = this.getTarget().getClass().getDeclaredField(filedName);
            DateTimeFormat dateTimeFormat = field.getAnnotation(DateTimeFormat.class);
            if (dateTimeFormat != null) {
                String pattern = dateTimeFormat.pattern();
                return new SimpleDateFormat(pattern).parse(String.valueOf(property.getValue()));
            }
            return property.getValue();
        } catch (NoSuchFieldException e) {
            return property.getValue();
        } catch (ParseException e) {
            return property.getValue();
        }
    }
}
